package com.vitabuybuy.tv.ui.tencent.liveroom.ui

import android.graphics.drawable.AnimationDrawable
import android.os.Bundle
import android.os.Handler
import android.view.View
import android.view.WindowManager
import android.widget.Button
import android.widget.FrameLayout
import android.widget.ImageView
import androidx.appcompat.app.AlertDialog
import androidx.core.content.ContextCompat
import androidx.core.os.bundleOf
import androidx.recyclerview.widget.LinearLayoutManager
import com.library.common.base.BaseActivity
import com.library.common.base.MessageModel
import com.library.common.base.appContext
import com.library.common.dto.MessageEvent
import com.library.common.ext.mmkv
import com.library.common.toast.XToast
import com.library.common.util.JsonUtil
import com.library.common.util.MMKVContancts
import com.tencent.rtmp.ui.TXCloudVideoView
import com.vitabuybuy.tv.R
import com.vitabuybuy.tv.adaptebinding.ImageAdapter
import com.vitabuybuy.tv.adaptebinding.TextAdapter
import com.vitabuybuy.tv.databinding.MlvbActivityLiveRoomAudienceBinding
import com.vitabuybuy.tv.ui.tencent.liveroom.roomutil.widget.LiveGoofsPopup
import com.vitabuybuy.tv.ui.tencent.liveroom.roomutil.widget.LiveProposalPopup
import com.vitabuybuy.tv.dialog.SharePopup
import com.vitabuybuy.tv.dialog.SpecSelectorDialog
import com.vitabuybuy.tv.dto.BannerDto
import com.vitabuybuy.tv.ui.cart.ConfirmOrderActivity
import com.vitabuybuy.tv.ui.mine.coin.RechargeRewardCoinActivity
import com.vitabuybuy.tv.ui.shopcenter.GoodsDetailsActivity
import com.vitabuybuy.tv.ui.shopcenter.store.StoreHomeActivity
import com.vitabuybuy.tv.ui.tencent.liveroom.IMLVBLiveRoomListener
import com.vitabuybuy.tv.ui.tencent.liveroom.MLVBLiveRoom
import com.vitabuybuy.tv.ui.tencent.liveroom.bean.GiftListBean
import com.vitabuybuy.tv.ui.tencent.liveroom.bean.LiveGoodsBean
import com.vitabuybuy.tv.ui.tencent.liveroom.roomutil.commondef.*
import com.vitabuybuy.tv.ui.tencent.liveroom.roomutil.misc.HintDialog
import com.vitabuybuy.tv.ui.tencent.liveroom.roomutil.widget.*
import com.vitabuybuy.tv.utils.EventCode
import org.greenrobot.eventbus.EventBus
import java.text.SimpleDateFormat
import java.util.*
import kotlin.collections.ArrayList

class AudienceLiveRoomActivity :
    BaseActivity<LiveRoomViewModel, MlvbActivityLiveRoomAudienceBinding>(),
    IMLVBLiveRoomListener {
    override val isUseBaseTitleBar: Boolean
        get() = false
    override val layoutId: Int
        get() = R.layout.mlvb_activity_live_room_audience
    private val mPusherList: MutableList<AnchorInfo>? = ArrayList()
    private val mPlayerViews: MutableList<RoomVideoView> = ArrayList()
    private var mChatMsgList: ArrayList<RoomListViewAdapter.TextChatMsg>? = null
    private var mChatMsgAdapter: RoomListViewAdapter.ChatMessageAdapter? = null
    private val mChatMsgGiftAdapter by lazy { ChatMsgGiftAdapter() }
    private val mTextMsgInputDialog by lazy { TextMsgInputDialog(mContext) }
    private val mGiftDialog by lazy { GiftListDialog(mContext) }
    private val specDialog by lazy { LiveSpecSelectorDialog(mContext) }
    private val mGoodDialog by lazy { LiveGoofsPopup(mContext) }
    private var mSwipeAnimationController: SwipeAnimationController? = null
    private var mLikeFrequencyControl: TCLikeFrequencyControl? = null//点赞频率的控制类

    private var mMLVBLiveRoom: MLVBLiveRoom? = null
    private var mRoomInfo: RoomInfo? = null
    private var liveGood: LiveGoodsBean? = null

    override fun onGetBundle(bundle: Bundle?) {
        mRoomInfo = bundle?.getSerializable("roomInfo") as RoomInfo
    }

    override fun initView(savedInstanceState: Bundle?) {
        window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
        mMLVBLiveRoom = MLVBLiveRoom.sharedInstance(appContext)
        mMLVBLiveRoom?.setListener(this)
        mBinding.mlvbVideoViewFullScreen.setLogMargin(12f, 12f, 80f, 60f)
        LiveProposalPopup(
            mContext
        ).showPopupWindow()
        mRoomInfo?.run {
            if (isExecutor) {
                mBinding.btnGroup.visibility = View.GONE
                mBinding.btnBidding.visibility = View.GONE
            } else {
                mBinding.btnGroup.visibility = View.VISIBLE
                mBinding.btnBidding.visibility = View.VISIBLE
            }
            ImageAdapter.setCircleImageUrl(
                mBinding.ivAuthorAvatar, authorAvatar, ContextCompat.getDrawable(
                    mContext,
                    R.drawable.beauty_ic_makeups_widow
                )
            )
            mBinding.btnFollow.text =
                if (attention) getString(R.string.already_success_follow) else getString(R.string.follow)
            mBinding.tvStoreName.text = authorName
            mBinding.tvAuthorId.text = "ID : $authorId"
            mBinding.tvRegion.text = String.format(
                getString(R.string.mlvb_view_count_region),
                audienceCount,
                authorRegion
            )
        }
        mMLVBLiveRoom?.run {
            enterRoom(mRoomInfo?.roomID, mRoomInfo?.mixedPlayURL,
                mBinding.mlvbVideoViewFullScreen,
                object : IMLVBLiveRoomListener.EnterRoomCallback {
                    override fun onError(errCode: Int, errInfo: String) {
                        errorGoBack(
                            getString(R.string.mlvb_join_live_room_error),
                            errCode,
                            errInfo
                        )
                    }

                    override fun onSuccess() {
                        viewModel.joinLive(mRoomInfo?.liveId)
                    }
                })
        }
        mBinding.mlvbGiftListView.apply {
            layoutManager = object : LinearLayoutManager(mContext, VERTICAL, false) {
                override fun canScrollVertically(): Boolean {
                    return false
                }

                override fun setStackFromEnd(stackFromEnd: Boolean) {
                    super.setStackFromEnd(true)
                }
            }
            adapter = mChatMsgGiftAdapter
        }
        mChatMsgList = ArrayList()
        mChatMsgAdapter = RoomListViewAdapter.ChatMessageAdapter(mContext, mChatMsgList)
        mBinding.mlvbChatListView.adapter = mChatMsgAdapter
        mSwipeAnimationController = SwipeAnimationController(mContext)
        mSwipeAnimationController?.setAnimationView(mBinding.mlvbRlChatLayout)
    }

    override fun observeData() {
        viewModel.giftAndCoin.observe(this, androidx.lifecycle.Observer {
            mGiftDialog.initData(it.giftList, it.mCoinValue)
            mGiftDialog.showPopupWindow()
        })
        viewModel.viewQuantity.observe(this, androidx.lifecycle.Observer {
            mBinding.tvRegion.text = String.format(
                getString(R.string.mlvb_view_count_region), it,
                mRoomInfo?.authorRegion
            )
        })
        viewModel.goodsList.observe(this, androidx.lifecycle.Observer {
            mGoodDialog.initData(it)
            mGoodDialog.showPopupWindow()
        })
        viewModel.goodDetails.observe(this, androidx.lifecycle.Observer {
            val bannerlist = ArrayList<BannerDto.SlideListBean>()
            for (str in it.images.split(";")) {
                val bannerDto = BannerDto.SlideListBean()
                bannerDto.image = str
                bannerlist.add(bannerDto)
            }
            specDialog.setSpecDatas(
                it.attributeList,
                it.goodsList,
                it.livePrice,
                if (bannerlist.isNotEmpty()) bannerlist[0].image else ""
            )
            specDialog.show()
        })
    }

    override fun eventHandling() {
        specDialog.onbuyNowClick = { goodId, buyNum ->
            ConfirmOrderActivity.openActivityByLive(
                mContext,
                goodId,
                buyNum,
                mRoomInfo?.liveId,
                ConfirmOrderActivity.BUY_NOW
            )
        }
        mBinding.clGoodeCard.setOnClickListener {
            liveGood?.run {
                GoodsDetailsActivity.openActivity(mContext, this.id)
            }
        }
        mBinding.btnAddToCart.setOnClickListener {
            liveGood?.run {
                viewModel.getDetails(this.id)
            }
        }
        mBinding.btnClose.setOnClickListener { onBackPressed() }
        //发送消息
        mBinding.mlvbRtmproomChatBtn.setOnClickListener { mTextMsgInputDialog.show() }
        mTextMsgInputDialog.setOnTextSendListener(object : TextMsgInputDialog.OnTextSendListener {
            override fun onTextSend(msg: String?) {
                msg?.run {
                    sendMessage(this)
                }
            }
        })
        mBinding.mlvbChatListView.setOnTouchListener { _, _ ->
            mBinding.mlvbLlControllerContainer.visibility = View.VISIBLE
            mBinding.ivJubao.visibility = View.INVISIBLE
            false
        }
        mBinding.clParentView.setOnTouchListener { _, event ->
            mBinding.mlvbLlControllerContainer.visibility = View.VISIBLE
            mBinding.ivJubao.visibility = View.INVISIBLE
            mSwipeAnimationController!!.processEvent(event)
        }
        mBinding.ivDianZan.setOnClickListener {
            if (mBinding.heartLayout != null) {
                mBinding.heartLayout.addFavor()
            }
            //点赞发送请求限制
            if (mLikeFrequencyControl == null) {
                mLikeFrequencyControl = TCLikeFrequencyControl()
                mLikeFrequencyControl?.init(2, 1)
            }
            if (mLikeFrequencyControl!!.canTrigger()) {
                //向ChatRoom发送点赞消息
                viewModel.livePraise(mRoomInfo?.liveId)
            }
        }
        mBinding.btnGift.setOnClickListener {
            viewModel.getGiftList(mRoomInfo?.liveId)
        }
        mBinding.btnBidding.setOnClickListener {
            StoreHomeActivity.openActivity(
                mContext,
                mRoomInfo?.authorId?.toInt(),
                mRoomInfo?.authorName,
                StoreHomeActivity.JUMP_BIDING_PAGE
            )
        }
        mBinding.btnGroup.setOnClickListener {
            StoreHomeActivity.openActivity(
                mContext,
                mRoomInfo?.authorId?.toInt(),
                mRoomInfo?.authorName,
                StoreHomeActivity.JUMP_GROUP_PAGE
            )
        }
        mGiftDialog.onCliclRechargeListener = {
            RechargeRewardCoinActivity.openActivity(mContext, it)
        }
        mGiftDialog.onClicSendkListener = { giftListBean: GiftListBean, quantity: Int ->
            mRoomInfo?.run {
                viewModel.sendGift(liveId, giftListBean, quantity)
            }
        }
        mBinding.btnFollow.setOnClickListener {
            mRoomInfo?.run {
                viewModel.collectOrcancel(authorId.toInt(), attention, isExecutor)
            }
        }
        mBinding.btnMore.setOnClickListener {
            if (mBinding.ivJubao.visibility == View.INVISIBLE) {
                mBinding.ivJubao.visibility = View.VISIBLE
            }
        }
        mBinding.btnShare.setOnClickListener {
            SharePopup(mContext).showPopupWindow()
        }
        mBinding.btnGoosList.setOnClickListener {
            mRoomInfo?.run {
                viewModel.getGoodsList(liveId)
            }
        }
        mGoodDialog.onViewBackPlayListener = {

        }
        mGoodDialog.onBuyNowListener = {
            viewModel.getDetails(it)
        }
        mBinding.ivJubao.setOnClickListener {
            mRoomInfo?.run {
                ReportLiveAnchorActivity.openActivity(mContext, this.liveId)
            }
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        mMLVBLiveRoom?.stopLocalPreview()
        recycleVideoView()
    }

    private fun errorGoBack(
        title: String,
        errCode: Int,
        errInfo: String
    ) {
        mMLVBLiveRoom?.exitRoom(null)
        val errinfo = "$errInfo[$errCode]"
        val spannableStrBuidler = when (errCode) {
            MLVBCommonDef.LiveRoomErrorCode.ERROR_LICENSE_INVALID -> {
                getString(R.string.license_is_error_pls_contact_admin)
            }
            MLVBCommonDef.LiveRoomErrorCode.ERROR_NOT_LOGIN -> {
                getString(R.string.user_is_no_login)
            }
            MLVBCommonDef.LiveRoomErrorCode.ERROR_NOT_IN_ROOM -> {
                getString(R.string.enter_live_room_error)
            }
            MLVBCommonDef.LiveRoomErrorCode.ERROR_PUSH -> {
                getString(R.string.playurl_is_error_or_author_already_exit)
            }
            MLVBCommonDef.LiveRoomErrorCode.ERROR_PARAMETERS_INVALID -> {
                getString(R.string.parameters_invalid)
            }
            MLVBCommonDef.LiveRoomErrorCode.ERROR_PLAY -> {
                getString(R.string.play_error)
            }
            MLVBCommonDef.LiveRoomErrorCode.ERROR_IM_FORCE_OFFLINE -> {
                getString(R.string.you_account_login_in_other_user)
            }
            10036 /*IM 创建聊天室数量超过限额错误*/ -> {
                getString(R.string.chat_room_number_error)
            }
            else -> {
                errinfo
            }
        }
        AlertDialog.Builder(mContext)
            .setCancelable(false)
            .setTitle(title).setMessage(spannableStrBuidler)
            .setNegativeButton(getString(R.string.mlvb_ok)) { _, _ ->
                viewModel.exitLive(mRoomInfo?.liveId)
            }.show()
    }

    private fun addMessageItem(
        userName: String, message: String,
        aligment: RoomListViewAdapter.TextChatMsg.Alignment
    ) {
        mContext.runOnUiThread {
            val TIME_FORMAT = SimpleDateFormat("HH:mm")
            mChatMsgList?.add(
                RoomListViewAdapter.TextChatMsg(
                    userName, TIME_FORMAT.format(Date()), message, aligment
                )
            )
            mChatMsgAdapter?.notifyDataSetChanged()
            mBinding.mlvbChatListView.post {
                mChatMsgList?.run {
                    mBinding.mlvbChatListView.setSelection(this.size - 1)
                }
            }
        }
    }

    private fun sendMessage(message: String) {
        mMLVBLiveRoom?.sendRoomTextMsg(message, object :
            IMLVBLiveRoomListener.SendRoomTextMsgCallback {
            override fun onError(errCode: Int, errInfo: String) {
                AlertDialog.Builder(
                    mContext,
                    R.style.MlvbRtmpRoomDialogTheme
                ).setMessage(errInfo)
                    .setTitle(getString(R.string.mlvb_send_msg_fail))
                    .setPositiveButton(
                        android.R.string.ok
                    ) { dialog, _ -> dialog.dismiss() }.show()
            }

            override fun onSuccess() {
                mRoomInfo?.userName?.run {
                    addMessageItem(
                        this, message,
                        RoomListViewAdapter.TextChatMsg.Alignment.LEFT
                    )
                }
            }
        })
    }

    override fun onBackPressed() {
        viewModel.exitLive(mRoomInfo?.liveId)
    }

    override fun handleEvent(msg: MessageModel) {
        when (msg.code) {
            1 -> {
                mMLVBLiveRoom?.run {
                    sendRoomCustomMsg(
                        TCMsgModelType.TCMsgModelType_MemberQuitRoom.toString(),
                        "",
                        object : IMLVBLiveRoomListener.SendRoomCustomMsgCallback {
                            override fun onSuccess() {
                                exitRoom(object : IMLVBLiveRoomListener.ExitRoomCallback {
                                    override fun onError(errCode: Int, errInfo: String) {}
                                    override fun onSuccess() {
                                        recycleVideoView()
                                        finish()
                                    }
                                })
                            }

                            override fun onError(errCode: Int, errInfo: String?) {
                                recycleVideoView()
                                finish()
                            }
                        })
                }
            }
            2 -> {
                //TODO 发送自定义点赞消息
                mMLVBLiveRoom?.run {
                    sendRoomCustomMsg(
                        TCMsgModelType.TCMsgModelType_Praise.toString(), "",
                        null
                    )
                }
            }
            3 -> {
                //TODO 发送自定义礼物消息
                val giftBean = msg.obj as GiftListBean
                giftBean.quantity = msg.arg1
                giftBean.name = mmkv.decodeString(MMKVContancts.USER_NICKNAME)
                mMLVBLiveRoom?.run {
                    sendRoomCustomMsg(
                        TCMsgModelType.TCMsgModelType_DanmaMsg.toString(),
                        JsonUtil.toJson(giftBean), null
                    )
                }
                mChatMsgGiftAdapter.setNewData(listOf(giftBean))
                Handler().postDelayed({
                    if (mChatMsgGiftAdapter.mData.isNotEmpty()) {
                        mChatMsgGiftAdapter.removeAt(mChatMsgGiftAdapter.mData.size - 1)
                    }
                }, 2200)
            }
            4 -> {
                mRoomInfo?.attention = !(msg.obj as Boolean)
                if (mRoomInfo?.attention == true) {
                    mBinding.btnFollow.text = getString(R.string.already_success_follow)
                    XToast.success(getString(R.string.already_success_follow))
                } else {
                    mBinding.btnFollow.text = getString(R.string.follow)
                    XToast.success(getString(R.string.follow))
                }
                EventBus.getDefault()
                    .post(MessageEvent(EventCode.update_attantion, mRoomInfo?.attention))
            }
            5 -> {
                mMLVBLiveRoom?.run {
                    sendRoomCustomMsg(
                        TCMsgModelType.TCMsgModelType_MemberEnterRoom.toString(),
                        "",
                        object : IMLVBLiveRoomListener.SendRoomCustomMsgCallback {
                            override fun onSuccess() {
                            }

                            override fun onError(errCode: Int, errInfo: String?) {
                            }
                        })
                }
                mMLVBLiveRoom?.run {
                    getCustomInfo(object : IMLVBLiveRoomListener.GetCustomInfoCallback {
                        override fun onGetCustomInfo(customInfo: MutableMap<String, Any>?) {
                            if (customInfo != null) {
                                if (customInfo["latest_product"].toString().isNotEmpty()) {
                                    liveGood = JsonUtil.fromJson(
                                        customInfo["latest_product"].toString(),
                                        LiveGoodsBean::class.java
                                    )
                                    liveGood?.run {
                                        mBinding.clGoodeCard.visibility = View.VISIBLE
                                        ImageAdapter.setNomalImageUrl(
                                            mBinding.ivPhoto,
                                            this.thumbnail,
                                            ContextCompat.getDrawable(
                                                mContext,
                                                R.drawable.default_image
                                            )
                                        )
                                        mBinding.tvTitle.text = this.getNameFormat()
                                        TextAdapter.setOldPrice(
                                            mBinding.tvOldPrice,
                                            this.salePrice
                                        )
                                        TextAdapter.setNowPrice(
                                            mBinding.tvNewPrice,
                                            this.livePrice
                                        )
                                    }
                                }
                            }
                        }

                        override fun onError(errCode: Int, errInfo: String?) {}
                    })
                }
            }
//            6 -> {
//                XToast.success(getString(R.string.already_add_to_cart))
//            }
        }
    }

//    override fun onPermissionDisable() {
//        AlertDialog.Builder(this, R.style.MlvbRtmpRoomDialogTheme)
//            .setMessage(getString(R.string.mlvb_permission_hint))
//            .setPositiveButton(android.R.string.ok) { _, _ -> finish() }
//    }

    /**
     * 错误回调
     * SDK 不可恢复的错误，一定要监听，并分情况给用户适当的界面提示
     *
     * @param errCode   错误码
     * @param errMsg    错误信息
     * @param extraInfo 额外信息，如错误发生的用户，一般不需要关注，默认是本地错误
     */
    override fun onError(
        errCode: Int, errMsg: String,
        extraInfo: Bundle
    ) {
        errorGoBack(getString(R.string.live_error), errCode, errMsg)
    }

    /**
     * 警告回调
     *
     * @param warningCode 错误码 TRTCWarningCode
     * @param warningMsg  警告信息
     * @param extraInfo   额外信息，如警告发生的用户，一般不需要关注，默认是本地错误
     */
    override fun onWarning(
        warningCode: Int, warningMsg: String,
        extraInfo: Bundle
    ) {
    }

    override fun onDebugLog(log: String) {}

    /**
     * 房间被销毁的回调
     * 主播退房时，房间内的所有用户都会收到此通知
     *
     * @param roomID 房间ID
     */
    override fun onRoomDestroy(roomID: String) {
        if (mRoomInfo?.createRoom == false) {
            HintDialog.Builder(mContext)
                .setTittle(getString(R.string.mlvb_system_msg))
                .setContent(
                    getString(
                        R.string.mlvb_live_room_destroy,
                        if (mRoomInfo != null) mRoomInfo?.roomInfo else "null"
                    )
                )
                .setButtonText(getString(R.string.mlvb_back))
                .setDismissListener { onBackPressed() }.show()
        }
    }

    /**
     * 收到新主播进房通知
     * 房间内的主播（和连麦中的观众）会收到新主播的进房事件，您可以调用 [MLVBLiveRoom.startRemoteView] 显示该主播的视频画面。
     *
     * @param anchorInfo 新进房用户信息
     * @note 直播间里的普通观众不会收到主播加入和推出的通知。
     */
    override fun onAnchorEnter(anchorInfo: AnchorInfo) {
        if (anchorInfo.userID == null) {
            return
        }
        val videoView = applyVideoView(anchorInfo.userID) ?: return
        if (mPusherList != null) {
            var exist = false
            for (item in mPusherList) {
                if (anchorInfo.userID.equals(item.userID, ignoreCase = true)) {
                    exist = true
                    break
                }
            }
            if (!exist) {
                mPusherList.add(anchorInfo)
            }
        }
        videoView.startLoading()
        mMLVBLiveRoom?.startRemoteView(anchorInfo, videoView.videoView, object :
            IMLVBLiveRoomListener.PlayCallback {
            override fun onBegin() {
                videoView.stopLoading(
                    mRoomInfo?.createRoom ?: false
                ) //推流成功，stopLoading 大主播显示出踢人的button
            }

            override fun onError(errCode: Int, errInfo: String) {
                onAnchorExit(anchorInfo)
                if (mRoomInfo?.createRoom == true) {
                    mMLVBLiveRoom?.kickoutJoinAnchor(anchorInfo.userID)
                }
            }

            override fun onEvent(event: Int, param: Bundle) {
                //TODO
            }
        })
    }

    /**
     * 收到主播退房通知
     * 房间内的主播（和连麦中的观众）会收到新主播的退房事件，您可以调用 [MLVBLiveRoom.stopRemoteView] 关闭该主播的视频画面。
     *
     * @param anchorInfo 退房用户信息
     * @note 直播间里的普通观众不会收到主播加入和推出的通知。
     */
    override fun onAnchorExit(anchorInfo: AnchorInfo) {
        if (mPusherList != null) {
            val it =
                mPusherList.iterator()
            while (it.hasNext()) {
                val item = it.next()
                if (anchorInfo.userID.equals(item.userID, ignoreCase = true)) {
                    it.remove()
                    break
                }
            }
        }
        mMLVBLiveRoom?.stopRemoteView(anchorInfo) //关闭远端视频渲染
        recycleVideoView(anchorInfo.userID)
    }

    /**
     * 收到观众进房通知
     *
     * @param audienceInfo 进房观众信息
     */
    override fun onAudienceEnter(audienceInfo: AudienceInfo) {
        viewModel.getViewQuantity(mRoomInfo?.liveId)
    }

    /**
     * 收到观众退房通知
     *
     * @param audienceInfo 退房观众信息
     */
    override fun onAudienceExit(audienceInfo: AudienceInfo) {
        viewModel.getViewQuantity(mRoomInfo?.liveId)
    }

    /**
     * 主播收到观众连麦请求时的回调
     *
     * @param anchorInfo 观众信息
     * @param reason     连麦原因描述
     */
    override fun onRequestJoinAnchor(
        anchorInfo: AnchorInfo, reason: String
    ) {
    }

    /**
     * 连麦观众收到被踢出连麦的通知
     * 连麦观众收到被主播踢除连麦的消息，您需要调用 [MLVBLiveRoom.kickoutJoinAnchor] 来退出连麦
     */
    override fun onKickoutJoinAnchor() {}

    /**
     * 收到请求跨房 PK 通知
     * 主播收到其他房间主播的 PK 请求
     * 如果同意 PK ，您需要调用 [MLVBLiveRoom.startRemoteView]  接口播放邀约主播的流
     *
     * @param anchorInfo 发起跨房连麦的主播信息
     */
    override fun onRequestRoomPK(anchorInfo: AnchorInfo) {}

    /**
     * 收到断开跨房 PK 通知
     */
    override fun onQuitRoomPK(anchorInfo: AnchorInfo) {}
    override fun onRecvRoomTextMsg(
        roomid: String,
        userid: String,
        userName: String,
        userAvatar: String,
        message: String
    ) {
        addMessageItem(userName, message, RoomListViewAdapter.TextChatMsg.Alignment.LEFT)
    }

    override fun onRecvRoomCustomMsg(
        roomID: String,
        userID: String,
        userName: String,
        userAvatar: String,
        cmd: String,
        message: String
    ) {
        when (cmd.toInt()) {
            TCMsgModelType.TCMsgModelType_MemberEnterRoom -> {
                addMessageItem(
                    userName,
                    getString(R.string.enter_live_room),
                    RoomListViewAdapter.TextChatMsg.Alignment.CENTER
                )
            }
            TCMsgModelType.TCMsgModelType_MemberQuitRoom -> {
                addMessageItem(
                    userName,
                    getString(R.string.quit_live_room),
                    RoomListViewAdapter.TextChatMsg.Alignment.CENTER
                )
            }
            TCMsgModelType.TCMsgModelType_Goods -> {
                liveGood = JsonUtil.fromJson(message, LiveGoodsBean::class.java)
                liveGood?.run {
                    mBinding.clGoodeCard.visibility = View.VISIBLE
                    ImageAdapter.setNomalImageUrl(
                        mBinding.ivPhoto,
                        this.thumbnail,
                        ContextCompat.getDrawable(mContext, R.drawable.default_image)
                    )
                    mBinding.tvTitle.text = this.getNameFormat()
                    TextAdapter.setOldPrice(
                        mBinding.tvOldPrice,
                        this.salePrice
                    )
                    TextAdapter.setNowPrice(mBinding.tvNewPrice, this.livePrice)
                }
            }
            TCMsgModelType.TCMsgModelType_Praise -> {
                if (mBinding.heartLayout != null) {
                    mBinding.heartLayout.addFavor()
                }
            }
            TCMsgModelType.TCMsgModelType_DanmaMsg -> {
                val giftBean = JsonUtil.fromJson(message, GiftListBean::class.java)
                giftBean.name = userName
                mChatMsgGiftAdapter.setNewData(listOf(giftBean))
                Handler().postDelayed({
                    if (mChatMsgGiftAdapter.mData.isNotEmpty()) {
                        mChatMsgGiftAdapter.removeAt(mChatMsgGiftAdapter.mData.size - 1)
                    }
                }, 2200)
            }
        }
    }

    inner class RoomVideoView(
        var videoView: TXCloudVideoView, button: Button,
        loadingBkg: FrameLayout, loadingImg: ImageView
    ) {
        var loadingBkg: FrameLayout
        var loadingImg: ImageView
        var kickButton: Button
        var userID: String? = null

        @JvmField
        var isUsed: Boolean = false
        fun startLoading() {
            kickButton.visibility = View.INVISIBLE
            loadingBkg.visibility = View.VISIBLE
            loadingImg.visibility = View.VISIBLE
            loadingImg.setImageResource(R.drawable.mlvb_linkmic_loading)
            val ad = loadingImg.drawable as AnimationDrawable
            ad.start()
        }

        fun stopLoading(showKickoutBtn: Boolean) {
            kickButton.visibility = if (showKickoutBtn) View.VISIBLE else View.GONE
            loadingBkg.visibility = View.GONE
            loadingImg.visibility = View.GONE
            val ad = loadingImg.drawable as AnimationDrawable
            ad.stop()
        }

        fun stopLoading() {
            kickButton.visibility = View.GONE
            loadingBkg.visibility = View.GONE
            loadingImg.visibility = View.GONE
            val ad = loadingImg.drawable as AnimationDrawable
            ad.stop()
        }

        fun setUsed(used: Boolean) {
            videoView.visibility = if (used) View.VISIBLE else View.GONE
            if (!used) {
                stopLoading(false)
            }
            isUsed = used
        }

        init {
            videoView.visibility = View.GONE
            this.loadingBkg = loadingBkg
            this.loadingImg = loadingImg
            isUsed = false
            kickButton = button
            kickButton.setOnClickListener {
                kickButton.visibility = View.INVISIBLE
                val userID = userID
                if (userID != null) {
                    mPusherList?.run {
                        for (item in this) {
                            if (userID.equals(item.userID, ignoreCase = true)) {
                                onAnchorExit(item)
                                break
                            }
                        }
                        mMLVBLiveRoom?.kickoutJoinAnchor(userID)
                    }
                }
            }
        }
    }

    @Synchronized
    fun applyVideoView(id: String?): RoomVideoView? {
        if (id == null) {
            return null
        }
        for (item in mPlayerViews) {
            if (!item.isUsed) {
                item.setUsed(true)
                item.userID = id
                return item
            } else {
                if (item.userID != null && item.userID == id) {
                    item.setUsed(true)
                    return item
                }
            }
        }
        return null
    }

    @Synchronized
    fun recycleVideoView(id: String) {
        for (item in mPlayerViews) {
            if (item.userID != null && item.userID == id) {
                item.userID = null
                item.setUsed(false)
            }
        }
    }

    @Synchronized
    fun recycleVideoView() {
        for (item in mPlayerViews) {
            item.userID = null
            item.setUsed(false)
        }
    }

    companion object {
        fun openActivity(mContext: BaseActivity<*, *>, roomInfo: RoomInfo?) {
            mContext.startActivity(
                bundleOf(Pair("roomInfo", roomInfo)), AudienceLiveRoomActivity::class.java
            )
        }
    }
}